package com.nb.hdj.baseClass;

import com.nb.hdj.data.HtAudioAndVideoEnum;
import com.nb.hdj.model.MultimediaManagement;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.lang3.StringUtils;

import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class SeleniumUtil extends SeleniumBase {

    private static final Logger logger = LoggerFactory.getLogger(SeleniumUtil.class);

    /**
     * 元素点击
     **/
    public boolean elementClick(WebDriver driver, By element) throws InterruptedException {
        if (!elementWaitHandle(driver, element, new SeleniumUtilInterface() {
            @Override
            public void action(WebElement element) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                element.click();
            }
        })) {
            logger.error("------点击元素:{}失败------", element);
            return false;
        }
        logger.info("------点击元素:{}成功------", element);
        return true;
    }

    /**
     * 被元素被蒙层遮住,或者loading遮住的 元素点击  此方法暂不可用 经验证
     **/
    public boolean elementVisualClick(WebDriver driver, By element) throws InterruptedException {
        if (!elementVisualWaitHandle(driver, element, new SeleniumUtilInterface() {
            @Override
            public void action(WebElement element) {
                element.click();
            }
        })) {
            logger.error("------点击可视元素:{}失败------", element);
            return false;
        }
        logger.info("------点击可视元素:{}成功------", element);
        return true;
    }

    /**
     * 元素清空
     */
    public boolean elementClear(WebDriver driver, By element) throws InterruptedException {
        if (!elementWaitHandle(driver, element, new SeleniumUtilInterface() {
            @Override
            public void action(WebElement element) {
                element.clear();
            }
        })) return false;
        return true;
    }


    /**
     * 数据输入
     **/
    public boolean elementSendKeys(WebDriver driver, By elementBy, final String elementInput) throws InterruptedException {
        if (!elementWaitHandle(driver, elementBy, new SeleniumUtilInterface() {
            @Override
            public void action(WebElement element) {
                element.sendKeys(elementInput);
            }
        })) return false;
        return true;
    }

    /**
     * 检查元素是否存在
     **/
    public boolean elementIsExit(WebDriver driver, By elementBy) {
        if (!elementIsExitBase(driver, elementBy)) return false;
        return true;
    }

    /**
     * 检查元素是否存在 自定义时间
     */
    public boolean elementIsExitTime(WebDriver driver, By elementBy, int time) {
        if (!elementIsExitBaseByTime(driver, elementBy, time)) return false;
        return true;
    }


    /**
     * 查找父类节点
     *
     * @return 返回当前的父节点
     **/
    public WebElement findFatherElement(WebDriver driver, By by) {
        WebElement element = driver.findElement(by);
        return element;
    }


    /**
     * 二次定位
     **/
    public WebElement findChildrenElement(WebDriver driver, By fatherBy, By childrenBy) {
        WebElement element = findFatherElement(driver, fatherBy);
        return element.findElement(childrenBy);
    }

    /**
     * 获取装元素的list
     **/
    public List<WebElement> getElements(WebDriver driver, By elementBy) {
        return getElementsBase(driver, elementBy);
    }

    /**
     * 获取元素的文本消息
     **/
    public String getElementText(WebDriver driver, final By elementBy) {
        return getElementBase(driver, elementBy).getText();
    }


    /**
     * 获取元素key所对应的value
     **/
    public String getElementAttribute(WebDriver driver, final By elementBy, String key) {
        return getElementBase(driver, elementBy).getAttribute(key);
    }


    /**
     * 判断元素的文本消息是否等于常量
     **/
    public boolean elementTextIsEqual(WebDriver driver, By elementBy, String text) {
        if (getElementBase(driver, elementBy).getText().equals(text)) return true;
        return false;
    }

    /**
     * 判断元素的文本消息是否包含特定常量
     **/
    public boolean elementTextIsContains(WebDriver driver, By elementBy, String text) {
        if (getElementBase(driver, elementBy).getText().contains(text)) {
            logger.info("------{}元素获取到的文本信息包含:{}------", elementBy, text);
            //System.out.println(getElementBase(driver, elementBy).getText());
            return true;
        } else {
            logger.error("------{}元素获取到的文本信息不包含:{}------", elementBy, text);
            return false;
        }
    }

    /**
     * 判断元素是否可见
     **/
    public boolean elementIsShow(WebDriver driver, By elementBy) {
        if (getElementBase(driver, elementBy).isDisplayed()) return true;
        return false;
    }

    /**
     * 线程强制休眠
     * @param ms
     */
    public void sleep(long ms){
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 刷新当前页面
     **/
    public void refreshPage(WebDriver driver) {
        try {
            driver.navigate().refresh();
        } catch (Exception e) {
            e.fillInStackTrace();
        }
    }

    /**
     * 关闭当前浏览器
     **/
    public void quitBrowser(WebDriver driver) {
        try {
            driver.quit();
        } catch (Exception e) {
            e.fillInStackTrace();
        }
    }

    /**
     * 元素输入流程操作  点击->清空->输入
     **/
    public boolean elementClickAndClearAndInput(WebDriver driver, By element, final String elementInput) throws InterruptedException {
        if (!elementWaitHandle(driver, element, new SeleniumUtilInterface() {
            @Override
            public void action(WebElement element) {
                try {
                    Thread.sleep(300);
                    element.click();
                    Thread.sleep(500);
                    element.clear();
                    Thread.sleep(500);
                    element.sendKeys(elementInput);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        })) {
            logger.error("------点击-清空-输入内容:{}-失败------", elementInput);
            return false;
        }
        logger.info("------点击-清空-输入内容:{}-成功------", elementInput);
        return true;
    }

    /**
     * 悬停到指定元素
     */
    public boolean hover(String xpath, WebDriver driver) {
        try {
            Thread.sleep(500);
            WebElement elementBase = getElementBase(driver, By.xpath(xpath));
            //WebElement elementBase = driver.findElement(By.xpath(xpath));
            Actions actions = new Actions(driver);
            actions.moveToElement(elementBase).build().perform();
            Thread.sleep(500);
            logger.info("------{}悬停到指定弹框提示元素-成功------", xpath);
            //String alertText= driver.findElement(By.xpath(xpath)).getText();
            //System.out.println(alertText);
            return true;
        } catch (Exception e) {
            logger.error("------{}悬停到指定弹框提示元素-失败------", xpath);
            return false;
        }
    }

    /**
     * 获取闪退提示窗体信息，与期望文本信息作对比
     */
    public boolean alertText(String xpath, String target, WebDriver driver) {
        boolean alertExist = hover(xpath, driver);
        boolean check = false;
        if (alertExist) {
            try {
                String alertText = driver.findElement(By.xpath(xpath)).getText();
                //System.out.println(alertText);
                if (StringUtils.isNotEmpty(alertText) && alertText.contains(target)) {
                    //log.info("存在服务器异常问题，请通知管理员及时修复");
                    check = true;
                } else {
                    check = false;
                }
            } catch (Exception e) {
                check = false;
                //log.error("未找到指定弹框元素！!!");
            }
        } else {
            check = false;
        }
        return check;
    }

    /**
     * 跳入iframe
     */
    public void switchToIframeById(WebDriver driver, String iframeId) {
        driver.switchTo().frame(getElementBase(driver, By.id(iframeId)));
        logger.info("------切换到id为:{}的iframe页面-成功------", iframeId);
    }

    /**
     * 跳出ifraame
     */
    public void exitIframe(WebDriver driver) {
        driver.switchTo().defaultContent();//跳出iframe
        logger.info("------切换到默认的iframe页面-成功------");
    }

    /**
     * 富文本输入内容  流程
     * @param driver
     */
    public void richTextInput(WebDriver driver, String mm){
        //点击富文本编辑器
        try {
            elementClick(driver, By.xpath(HtAudioAndVideoEnum.RICH_TEXT_BUTTON.getValue()));
            //切换符文本iframe
            switchToIframeById(driver,HtAudioAndVideoEnum.RICH_TEXT_IFRAME.getValue());
            //富文本输入内容
            elementClickAndClearAndInput(driver,By.id(HtAudioAndVideoEnum.RICH_TEXT_INPUT.getValue()),mm);
            exitIframe(driver);
            //点击保存编辑
            elementClick(driver, By.xpath(HtAudioAndVideoEnum.RICH_TEXT_CONFIRM.getValue()));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    /**
     * 遍历获取下拉列表的值存放到集合里
     */
    public List<String> getLiForUlValues(WebDriver driver, String ulClassName, String liClassName) {
        List<WebElement> elements = driver.findElements(By.xpath("(//ul[@class='" + ulClassName + "']/li[@class='" + liClassName + "'])"));
        List<String> liValues = new ArrayList<>();
        for (WebElement element : elements) {
            liValues.add(element.getText());
        }
        return liValues;
    }

    /**
     * 点击下拉列表里最后一个元素
     */
    public void clickLastLiElement(WebDriver driver, String ulClassName, String liClassName) {
        try {
            elementClick(driver, By.xpath("(//ul[@class='" + ulClassName + "']/li[@class='" + liClassName + "'])[last()]/span"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 等待loading元素加载完再点击元素  方法不可用
     *
     * @param driver
     * @param element
     * @return
     */
    public boolean loadingElement(WebDriver driver, By element) {
        int times = 0;
        boolean loadingExist = elementIsExit(driver, element);
        while (loadingExist) {
            try {
                Thread.sleep(2000);
                loadingElement(driver, element);
                times += 2000;
                System.out.println(times);
                if (times >= 10000) {
                    loadingExist = false;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    /**
     * 等待直到元素没有出现  自定义超时
     *
     * @param driver
     * @param locator
     * @param timeOutInSeconds
     * @return
     */
    public Boolean waitUntilElementNotPresent(WebDriver driver, final By locator, long timeOutInSeconds) {
        Boolean isPresent = true;
        for (int i = 0; i < timeOutInSeconds; i++) {
            isPresent = elementIsExitTime(driver, locator, 2);
            if (false == isPresent) {
                break;
            } else {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                logger.info("等待不超过【" + timeOutInSeconds + "】秒的加载图标消失,等待了【" + (i + 1) + "】秒");
            }
        }
        return isPresent;
    }

    /**
     * 非input控件上传 文件
     *
     * @param filePath 文件路径
     */
    public void autoUploadFile(String filePath) {
        //文件需要导入
        File file = new File(filePath);
        StringSelection stringSelection = new StringSelection(file.getAbsolutePath());
        //复制到剪贴板
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
        Robot robot = null;
        try {
            robot = new Robot();
        } catch (AWTException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // Cmd + Tab是必需的，因为它会启动Java应用程序，浏览器会失去焦点
        robot.keyPress(KeyEvent.VK_META);
        robot.keyPress(KeyEvent.VK_TAB);
        robot.keyRelease(KeyEvent.VK_META);
        robot.keyRelease(KeyEvent.VK_TAB);
        robot.delay(2000);
        //打开转到窗口的快捷键是命令+shift + G，适用于MAC
        robot.keyPress(KeyEvent.VK_META);
        robot.keyPress(KeyEvent.VK_SHIFT);
        robot.keyPress(KeyEvent.VK_G);
        robot.keyRelease(KeyEvent.VK_META);
        robot.keyRelease(KeyEvent.VK_SHIFT);
        robot.keyRelease(KeyEvent.VK_G);
        //粘贴剪贴板的值
        robot.keyPress(KeyEvent.VK_META);
        robot.keyPress(KeyEvent.VK_V);
        robot.keyRelease(KeyEvent.VK_META);
        robot.keyRelease(KeyEvent.VK_V);
        //按Enter键关闭Goto窗口和上传窗口
        robot.keyPress(KeyEvent.VK_ENTER);
        robot.keyRelease(KeyEvent.VK_ENTER);
        robot.delay(1000);
        robot.keyPress(KeyEvent.VK_ENTER);
        robot.keyRelease(KeyEvent.VK_ENTER);

    }

    /**
     * 文件上传
     *
     * @param filePath
     */
    public void uploadFile(String filePath) {
        logger.info("上传文件：" + filePath);
        try {
            String osName = System.getProperty("os.name");
            File file = new File(filePath);
            StringSelection stringSelection = new StringSelection(file.getAbsolutePath());
            // Copy to clipboard
            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
            Robot robot = new Robot();
            if (osName.contains("Mac")) {
                // Cmd + Tab is needed since it launches a Java app and the browser looses focus
                robot.keyPress(KeyEvent.VK_META);
                robot.keyPress(KeyEvent.VK_TAB);
                robot.keyRelease(KeyEvent.VK_META);
                robot.keyRelease(KeyEvent.VK_TAB);
                robot.delay(500);
                // Open Goto window shortkey is commmand +shift + G,
                //adpate to MAC
                robot.keyPress(KeyEvent.VK_META);
                robot.keyPress(KeyEvent.VK_SHIFT);
                robot.keyPress(KeyEvent.VK_G);
                robot.keyRelease(KeyEvent.VK_META);
                robot.keyRelease(KeyEvent.VK_SHIFT);
                robot.keyRelease(KeyEvent.VK_G);
                robot.delay(2000);
                // Paste the clipboard value
                robot.keyPress(KeyEvent.VK_META);
                robot.keyPress(KeyEvent.VK_V);
                robot.keyRelease(KeyEvent.VK_META);
                robot.keyRelease(KeyEvent.VK_V);
                robot.delay(2000);
                // Press Enter key to close the Goto window and
                // Upload window
                robot.keyPress(KeyEvent.VK_ENTER);
                robot.keyRelease(KeyEvent.VK_ENTER);
                robot.delay(2000);
                robot.keyPress(KeyEvent.VK_ENTER);
                robot.keyRelease(KeyEvent.VK_ENTER);
                robot.delay(2000);
            } else if (osName.contains("Windows")) {
                robot.keyPress(KeyEvent.VK_TAB);
                robot.delay(100);
                robot.keyRelease(KeyEvent.VK_TAB);
                robot.keyPress(KeyEvent.VK_TAB);
                robot.delay(100);
                robot.keyRelease(KeyEvent.VK_TAB);
                robot.keyPress(KeyEvent.VK_ENTER);
                robot.delay(100);
                robot.keyRelease(KeyEvent.VK_ENTER);
                robot.keyPress(KeyEvent.VK_CONTROL);
                robot.keyPress(KeyEvent.VK_V);
                robot.keyRelease(KeyEvent.VK_V);
                robot.keyRelease(KeyEvent.VK_CONTROL);
                robot.delay(100);
                robot.keyRelease(KeyEvent.VK_TAB);
                robot.keyPress(KeyEvent.VK_ENTER);
                robot.delay(100);
                robot.keyRelease(KeyEvent.VK_ENTER);
            } else {
                logger.warn("仅支持 Mac os 或 Windows");
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    /**
     * 下滑页面到目标位置
     */
    public void slideTargetPosition(WebDriver driver,By targetElement){
        String script = "return arguments[0].scrollIntoView();";
        WebElement element = getElementBase(driver, targetElement);
        ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
